﻿using System;
using System.Xml;
using HuaXingSDK.Reply;

namespace HuaXingSDK
{
    public abstract class HXResponse : HXFrom
    {
        public string MerchantId { get; internal set; }
        public string BankId { get; internal set; }
        public string OldReqseqNo { get; internal set; }

        protected HXResponse(string outerXml) : base(outerXml)
        {
        }

        protected override object GetValue(Type propertyType, XmlNode node)
        {
            if (propertyType.IsEnum)
            {
                if (propertyType == typeof(HXOrderStatus))
                {
                    if (node.InnerText.OICEquals("ORDER_COMPLETED"))
                        return HXOrderStatus.订单完成;
                    if (node.InnerText.OICEquals("ORDER_PRE_AUTHING"))
                        return HXOrderStatus.订单预授权中;
                    throw new HXException($"无法识别的{nameof(HXOrderStatus)}内容：{node.InnerText}。");
                }
                if (propertyType == typeof(HXReturnStatus))
                {
                    return (HXReturnStatus)node.InnerText.Trim()[0];
                }
                if (propertyType == typeof(HXIDType))
                {
                    if ("1010".Equals(node.InnerText))
                        return HXIDType.居民身份证;
                    throw new HXException($"无法识别的{nameof(HXIDType)}内容:{node.InnerText}。");
                }
                if (propertyType == typeof(HXDFFlag))
                {
                    return (HXDFFlag)node.InnerText.Trim()[0];
                }
                if (propertyType == typeof(HXHeaderStatus))
                {
                    return (HXHeaderStatus)node.InnerText.Trim()[0];
                }
            }
            
            return base.GetValue(propertyType, node);
        }
    }

    public abstract class HXResponse<T> : HXResponse where T : HXReply
    {
        protected HXResponse(string outerXml) : base(outerXml)
        {
        }

        public abstract T ToReply();
    }

    public abstract class HXSimpleResponse : HXResponse<RepSimple>
    {
        protected HXSimpleResponse(string outerXml) : base(outerXml)
        {
        }

        public override RepSimple ToReply()
        {
            return new RepSimple(this);
        }
    }

    public abstract class HXSyncResponse : HXResponse
    {
        public string ServerFlow { get; internal set; }
        public int ServerDate { get; internal set; }
        public int ServerTime { get; internal set; }
        public HXHeaderStatus Status { get; internal set; }
        public string ErrorCode { get; internal set; }
        public string ErrorMsg { get; internal set; }
        public string BodyErrorMsg { get; internal set; }

        protected HXSyncResponse(string outerXml) : base(outerXml)
        {
        }

        protected override void SetValue(XmlNode node)
        {
            if (node.Name.OICEquals(nameof(ErrorMsg)) && node.ParentNode != null && node.ParentNode.Name.OICEquals(BODY))
            {
                if (string.IsNullOrEmpty(node.InnerText) == false)
                    BodyErrorMsg = node.InnerText;
            }
            else
            {
                base.SetValue(node);
            }
        }
    }
}
